'Description: Calls the "Browse For Folder Dialog" without need for an OCX


'Place the following code in under a command button or in a menu, etc...

  Dim BI As BROWSEINFO
  Dim nFolder As Long
  Dim IDL As ITEMIDLIST
  Dim pIdl As Long
  Dim sPath As String
  Dim SHFI As SHFILEINFO
  
  With BI
    ' The dialog's owner window...
    .hOwner = Me.hWnd
    
    ' Set the Browse dialog root folder
    nFolder = GetFolderValue(m_wCurOptIdx)
    
    ' Fill the item id list with the pointer of the selected folder item, rtns 0 on success
    ' ==================================================
    ' If this function fails because the selected folder doesn't exist,
    ' .pidlRoot will be uninitialized & will equal 0 (CSIDL_DESKTOP)
    ' and the root will be the Desktop.
    ' DO NOT specify the CSIDL_ constants for .pidlRoot !!!!
    ' The SHBrowseForFolder() call below will generate a fatal exception
    ' (GPF) if the folder indicated by the CSIDL_ constant does not exist!!
    ' ==================================================
    If SHGetSpecialFolderLocation(ByVal Me.hWnd, ByVal nFolder, IDL) = NOERROR Then
      .pidlRoot = IDL.mkid.cb
    End If
    
    ' Initialize the buffer that rtns the display name of the selected folder
    .pszDisplayName = String$(MAX_PATH, 0)
    
    ' Set the dialog's banner text
    .lpszTitle = "Browsing is limited to: " & optFolder(m_wCurOptIdx).Caption
    
    ' Set the type of folders to display & return
    ' -play with these option constants to see what can be returned
    .ulFlags = GetReturnType()
    
  End With
  
  ' Clear previous return vals before the
  ' dialog is shown (it might be cancelled)
  txtPath = ""
  txtDisplayName = ""
  pic16Icon.Picture = LoadPicture()   ' clears prev icon
  pic32Icon.Picture = LoadPicture()
  
  ' Show the Browse dialog
  pIdl = SHBrowseForFolder(BI)
  
  ' If the dialog was cancelled...
  If pIdl = 0 Then Exit Sub
    
  ' Fill sPath w/ the selected path from the id list
  ' (will rtn False if the id list can't be converted)
  sPath = String$(MAX_PATH, 0)
  SHGetPathFromIDList ByVal pIdl, ByVal sPath

  ' Display the path and the name of the selected folder
  txtPath = Left(sPath, InStr(sPath, vbNullChar) - 1)
  txtDisplayName = Left$(BI.pszDisplayName, _
                             InStr(BI.pszDisplayName, vbNullChar) - 1)
  
  ' Get the 16x16 icon info from the id list using the pidl
  SHGetFileInfo ByVal pIdl, 0&, SHFI, Len(SHFI), _
                       SHGFI_PIDL Or SHGFI_ICON Or SHGFI_SMALLICON
  ' The 16x16 icon handle rtnd in SHFI.hIcon is stretched to 32x32.
  ' DrawIconEx() will shrink (or stretch) the icon per it's cxWidth & cyWidth params
  DrawIconEx pic16Icon.hdc, 0, 0, SHFI.hIcon, 16, 16, 0, 0, DI_NORMAL
  pic16Icon.Refresh
  
  ' Get the 32x32 icon info from the id list
  SHGetFileInfo ByVal pIdl, 0&, SHFI, Len(SHFI), _
                       SHGFI_PIDL Or SHGFI_ICON
  ' SHFI.hIcon is OK here so DrawIcon() can be used
  DrawIcon pic32Icon.hdc, 0, 0, SHFI.hIcon
  pic32Icon.Refresh
  
  ' Frees the memory SHBrowseForFolder()
  ' allocated for the pointer to the item id list
  CoTaskMemFree pIdl
  
'End of Code------------------------------------------------------------------------------------






'Module Declarations ---------------------------------------------------------------------------

' Objects in the shells namespace are assigned item identifiers and item
' identifier lists. An item identifier uniquely identifies an item within its parent
' folder. An item identifier list uniquely identifies an item within the shells
' namespace by tracing a path to the item from the desktop.

' An item identifier is defined by the variable-length SHITEMID structure.
' The first two bytes of this structure specify its size, and the format of
' the remaining bytes depends on the parent folder, or more precisely
' on the software that implements the parent folders IShellFolder interface.
' Except for the first two bytes, item identifiers are not strictly defined, and
' applications should make no assumptions about their format.
Type SHITEMID   ' mkid
    cb As Long       ' Size of the ID (including cb itself)
    abID() As Byte  ' The item ID (variable length)
End Type

' The ITEMIDLIST structure defines an element in an item identifier list
' (the only member of this structure is an SHITEMID structure). An item
' identifier list consists of one or more consecutive ITEMIDLIST structures
' packed on byte boundaries, followed by a 16-bit zero value. An application
' can walk a list of item identifiers by examining the size specified in each
' SHITEMID structure and stopping when it finds a size of zero. A pointer
' to an item identifier list, is sometimes called a PIDL (pronounced piddle)
Type ITEMIDLIST   ' idl
    mkid As SHITEMID
End Type

' Converts an item identifier list to a file system path.
' Returns TRUE if successful or FALSE if an error occurs, for example,
' if the location specified by the pidl parameter is not part of the file system.
Declare Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" _
                              (ByVal pIdl As Long, ByVal pszPath As String) As Long

' Retrieves the location of a special (system) folder.
' Returns NOERROR if successful or an OLE-defined error result otherwise.
Declare Function SHGetSpecialFolderLocation Lib "shell32.dll" _
                              (ByVal hwndOwner As Long, ByVal nFolder As Long, _
                              pIdl As ITEMIDLIST) As Long

' SHGetSpecialFolderLocation successful rtn val
Public Const NOERROR = 0

' SHGetSpecialFolderLocation nFolder params:
' Most folder locations are stored in:
' [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders]
' Value specifying the types of folders to be listed in the dialog box as well as other
' options. This member can be 0 or one of the following values:

' Windows desktop, virtual folder at the root of the name space.
Public Const CSIDL_DESKTOP = &H0

' File system directory that contains the user's program groups
' (which are also file system directories).
Public Const CSIDL_PROGRAMS = &H2

' Control Panel, virtual folder containing icons for the control panel applications.
Public Const CSIDL_CONTROLS = &H3

' Printers folder, virtual folder containing installed printers.
Public Const CSIDL_PRINTERS = &H4

' File system directory that serves as a common respository for documents.
Public Const CSIDL_PERSONAL = &H5   ' (Documents folder)

' File system directory that contains the user's favorite Internet Explorer URLs.
Public Const CSIDL_FAVORITES = &H6

' File system directory that corresponds to the user's Startup program group.
Public Const CSIDL_STARTUP = &H7

' File system directory that contains the user's most recently used documents.
Public Const CSIDL_RECENT = &H8   ' (Recent folder)

' File system directory that contains Send To menu items.
Public Const CSIDL_SENDTO = &H9

' Recycle bin, file system directory containing file objects in the user's recycle bin.
' The location of this directory is not in the registry; it is marked with the hidden and
' system attributes to prevent the user from moving or deleting it.
Public Const CSIDL_BITBUCKET = &HA

' File system directory containing Start menu items.
Public Const CSIDL_STARTMENU = &HB

' File system directory used to physically store file objects on the desktop
' (not to be confused with the desktop folder itself).
Public Const CSIDL_DESKTOPDIRECTORY = &H10

' My Computer, virtual folder containing everything on the local computer: storage
' devices, printers, and Control Panel. The folder may also contain mapped network drives.
Public Const CSIDL_DRIVES = &H11

' Network Neighborhood, virtual folder representing the top level of the network hierarchy.
Public Const CSIDL_NETWORK = &H12

' File system directory containing objects that appear in the network neighborhood.
Public Const CSIDL_NETHOOD = &H13

' Virtual folder containing fonts.
Public Const CSIDL_FONTS = &H14

' File system directory that serves as a common repository for document templates.
Public Const CSIDL_TEMPLATES = &H15   ' (ShellNew folder)

'========================================================

' Frees memory allocated by SHBrowseForFolder()
Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal pv As Long)

' Displays a dialog box that enables the user to select a shell folder.
' Returns a pointer to an item identifier list that specifies the location
' of the selected folder relative to the root of the name space. If the user
' chooses the Cancel button in the dialog box, the return value is NULL.
Declare Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" _
                              (lpBrowseInfo As BROWSEINFO) As Long ' ITEMIDLIST

' Contains parameters for the the SHBrowseForFolder function and receives
' information about the folder selected by the user.
Public Type BROWSEINFO   ' bi
    
    ' Handle of the owner window for the dialog box.
    hOwner As Long
    
    ' Pointer to an item identifier list (an ITEMIDLIST structure) specifying the location
    ' of the "root" folder to browse from. Only the specified folder and its subfolders
    ' appear in the dialog box. This member can be NULL, and in that case, the
    ' name space root (the desktop folder) is used.
    pidlRoot As Long
    
    ' Pointer to a buffer that receives the display name of the folder selected by the
    ' user. The size of this buffer is assumed to be MAX_PATH bytes.
    pszDisplayName As String
    
    ' Pointer to a null-terminated string that is displayed above the tree view control
    ' in the dialog box. This string can be used to specify instructions to the user.
    lpszTitle As String
    
    ' Value specifying the types of folders to be listed in the dialog box as well as
    ' other options. This member can include zero or more of the following values below.
    ulFlags As Long
    
    ' Address an application-defined function that the dialog box calls when events
    ' occur. For more information, see the description of the BrowseCallbackProc
    ' function. This member can be NULL.
    lpfn As Long
    
    ' Application-defined value that the dialog box passes to the callback function
    ' (if one is specified).
    lParam As Long
    
    ' Variable that receives the image associated with the selected folder. The image
    ' is specified as an index to the system image list.
    iImage As Long

End Type

' BROWSEINFO ulFlags values:
' Value specifying the types of folders to be listed in the dialog box as well as
' other options. This member can include zero or more of the following values:

' Only returns file system directories. If the user selects folders
' that are not part of the file system, the OK button is grayed.
Public Const BIF_RETURNONLYFSDIRS = &H1

' Does not include network folders below the domain level in the tree view control.
' For starting the Find Computer
Public Const BIF_DONTGOBELOWDOMAIN = &H2

' Includes a status area in the dialog box. The callback function can set
' the status text by sending messages to the dialog box.
Public Const BIF_STATUSTEXT = &H4

' Only returns file system ancestors. If the user selects anything other
' than a file system ancestor, the OK button is grayed.
Public Const BIF_RETURNFSANCESTORS = &H8

' Only returns computers. If the user selects anything other
' than a computer, the OK button is grayed.
Public Const BIF_BROWSEFORCOMPUTER = &H1000

' Only returns (network) printers. If the user selects anything other
' than a printer, the OK button is grayed.
Public Const BIF_BROWSEFORPRINTER = &H2000

Declare Function DrawIcon Lib "user32" (ByVal hdc As Long, _
ByVal x As Long, ByVal y As Long, ByVal hIcon As Long) As Boolean

Declare Function DrawIconEx Lib "user32" (ByVal hdc As Long, _
ByVal xLeft As Long, ByVal yTop As Long, ByVal hIcon As Long, _
ByVal cxWidth As Long, ByVal cyWidth As Long, ByVal istepIfAniCur As Long, _
ByVal hbrFlickerFreeDraw As Long, ByVal diFlags As Long) As Boolean

Declare Function SHGetFileInfo Lib "Shell32" Alias "SHGetFileInfoA" _
(ByVal pszPath As Any, ByVal dwFileAttributes As Long, _
psfi As SHFILEINFO, ByVal cbFileInfo As Long, ByVal uFlags As Long) As Long

' DrawIconEx() diFlags values:
Public Const DI_MASK = &H1
Public Const DI_IMAGE = &H2
Public Const DI_NORMAL = &H3
Public Const DI_COMPAT = &H4
Public Const DI_DEFAULTSIZE = &H8

' pszPath:
' Pointer to a buffer that contains the path and filename. Both absolute and
' relative paths are valid. If uFlags includes the SHGFI_PIDL, value pszPath
' must be the address of an ITEMIDLIST structure that contains the list of
' item identifiers that uniquely identifies the file within the shell's name
' space. This string can use either short (the 8.3 form) or long filenames.

' dwFileAttributes:
' Array of file attribute flags (FILE_ATTRIBUTE_ values). If uFlags does not
' include the SHGFI_USEFILEATTRIBUTES value, this parameter is ignored.

Public Const FILE_ATTRIBUTE_READONLY = &H1
Public Const FILE_ATTRIBUTE_HIDDEN = &H2
Public Const FILE_ATTRIBUTE_SYSTEM = &H4
Public Const FILE_ATTRIBUTE_DIRECTORY = &H10
Public Const FILE_ATTRIBUTE_ARCHIVE = &H20
Public Const FILE_ATTRIBUTE_NORMAL = &H80
Public Const FILE_ATTRIBUTE_TEMPORARY = &H100
Public Const FILE_ATTRIBUTE_COMPRESSED = &H800

' psfi and cbFileInfo:
' Address and size, in bytes, of the SHFILEINFO structure that receives the
' file information.

' Maximun long filename path length
Public Const MAX_PATH = 260

Type SHFILEINFO   ' shfi
    hIcon As Long
    iIcon As Long
    dwAttributes As Long
    szDisplayName As String * MAX_PATH
    szTypeName As String * 80
End Type

' uFlags:
' Flag that specifies the file information to retrieve. This parameter can
' be a combination of the following values:

' Modifies SHGFI_ICON, causing the function to retrieve the file's large icon.
Public Const SHGFI_LARGEICON = &H0&

' Modifies SHGFI_ICON, causing the function to retrieve the file's small icon.
Public Const SHGFI_SMALLICON = &H1&

' Modifies SHGFI_ICON, causing the function to retrieve the file's open icon.
' A container object displays an open icon to indicate that the container is open.
Public Const SHGFI_OPENICON = &H2&

' Modifies SHGFI_ICON, causing the function to retrieve a shell-sized icon.
' If this flag is not specified, the function sizes the icon according to the
' system metric values.
Public Const SHGFI_SHELLICONSIZE = &H4&

' Indicates that pszPath is the address of an ITEMIDLIST structure rather than a
' path name.
Public Const SHGFI_PIDL = &H8&

' Indicates that the function should use the dwFileAttributes parameter.
Public Const SHGFI_USEFILEATTRIBUTES = &H10&

' Retrieves the handle of the icon that represents the file and the index of the
' icon within the system image list. The handle is copied to the hIcon member
' of the structure specified by psfi, and the index is copied to the iIcon member.
' The return value is the handle of the system image list.
Public Const SHGFI_ICON = &H100&

' Retrieves the display name for the file. The name is copied to the szDisplayName
' member of the structure specified by psfi. The returned display name uses the
' long filename, if any, rather than the 8.3 form of the filename.
Public Const SHGFI_DISPLAYNAME = &H200&

' Retrieves the string that describes the file's type. The string is copied to the
' szTypeName member of the structure specified by psfi.
Public Const SHGFI_TYPENAME = &H400&

' Retrieves the file attribute flags. The flags are copied to the dwAttributes
' member of the structure specified by psfi.
Public Const SHGFI_ATTRIBUTES = &H800&

' Retrieves the name of the file that contains the icon representing the file.
' The name is copied to the szDisplayName member of the structure specified by psfi.
Public Const SHGFI_ICONLOCATION = &H1000&

' Returns the type of the executable file if pszPath identifies an executable file.
' To retrieve the executable file type, uFlags must specify only SHGFI_EXETYPE.
' The return value specifies the type of the executable file:
' 0 Nonexecutable file or an error condition.
' LOWORD = NE or PEHIWORD = 3.0, 3.5, or 4.0  Windows application
' LOWORD = MZHIWORD = 0                               MS-DOS .EXE, .COM or .BAT file
' LOWORD = PEHIWORD = 0                               Win32 console application
Public Const SHGFI_EXETYPE = &H2000&

' Retrieves the index of the icon within the system image list. The index is copied
' to the iIcon member of the structure specified by psfi. The return value is the
' handle of the system image list.
Public Const SHGFI_SYSICONINDEX = &H4000&

' Modifies SHGFI_ICON, causing the function to add the link overlay to the file's icon.
Public Const SHGFI_LINKOVERLAY = &H8000&

' Modifies SHGFI_ICON, causing the function to blend the file's icon with the system
' highlight color.
Public Const SHGFI_SELECTED = &H10000

